#include "StdAfx.h"
#include "VertexUnitTests.h"
#include "VertexDirectory.h"
#include "Graph.h"
#include "Group.h"
#include <vector>

TestUtils::TestResult CheckVertexNeighbours() 
{
	// n=8, w=5
	bool nameArr1[] = {0,0,0,1,1,1,1,1};
	vector<bool> name1 (nameArr1, nameArr1+sizeof(nameArr1)/sizeof(bool));
	Vertex* vertex1 = new Vertex(name1);
	bool nameArr2[] = {1,0,0,1,1,1,0,1};
	vector<bool> name2 (nameArr2, nameArr2+sizeof(nameArr2)/sizeof(bool));
	Vertex* vertex2 = new Vertex(name2);
	bool nameArr3[] = {1,1,0,1,1,1,0,0};
	vector<bool> name3 (nameArr3, nameArr3+sizeof(nameArr3)/sizeof(bool));
	Vertex* vertex3 = new Vertex(name3);
	TestUtils::TestResult res = TestUtils::VerifyIsTrue(true == vertex1->Neighbours(vertex2),"Neighbouring vertices were reported as not neighbours");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	
	res = TestUtils::VerifyIsTrue(true == vertex3->Neighbours(vertex2),"Neighbouring vertices were reported as not neighbours");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(false == vertex1->Neighbours(vertex3),"Vertices were reported as neighbours");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	// now check that everything is symmetric: a vertex a is neighbour of vertex b iff vertex b is neighbour of vertex a
	res = TestUtils::VerifyIsTrue(true == vertex2->Neighbours(vertex1),"Neighbouring vertices were reported as not neighbours");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(true == vertex2->Neighbours(vertex3),"Neighbouring vertices were reported as not neighbours");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(false == vertex3->Neighbours(vertex1),"Vertices were reported as neighbours");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	return TestUtils::TestPassed;
}


TestUtils::TestResult RemoveAndAddNeighbour()
{
	// n=4, w=2
	bool nameArr1[] = {0,1,1,0};
	vector<bool> name1 (nameArr1, nameArr1+sizeof(nameArr1)/sizeof(bool));
	Vertex* vertex1 = new Vertex(name1);
	bool nameArr2[] = {1,1,0,0};
	vector<bool> name2 (nameArr2, nameArr2+sizeof(nameArr2)/sizeof(bool));
	Vertex* vertex2 = new Vertex(name2);
	int vertexRank = vertex1->Rank();
	vertex1->RemoveNeighbour(vertex2);
	TestUtils::TestResult res = TestUtils::VerifyIsTrue(false == vertex1->NeighboursInGraph(vertex2),"neighbour wasn't removed from vertex neighbour list");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(true == vertex1->NeighboursNotInGraph(vertex2),"neighbour wasn't added to vertex neighbour list (not in graph)");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(vertexRank -1 == vertex1->Rank(),"rank not updated whan removing from vertex neighbour list");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	vertex1->AddNeighbour(vertex2);
	res = TestUtils::VerifyIsTrue(true == vertex1->NeighboursInGraph(vertex2),"neighbour wasn't added to vertex neighbour list");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(false == vertex1->NeighboursNotInGraph(vertex2),"neighbour wasn't removed from vertex neighbour list (not in graph)");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(vertexRank == vertex1->Rank(),"rank not updated whan adding to vertex neighbour list");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	return TestUtils::TestPassed;
}



# if 0
// this test creates several vertices, adds them to the vertex directory, and then moves
// one of the vertices from the graph to a group and checks that the vertex (and its 
// neighbours) were updated accordingly
TestUtils::TestResult MoveVertexToGroup()
{
	Graph g;
	Group group;
	// create 4 vertices (n=8, w=5)
	int nameArr1[] = {0,0,0,1,1,1,1,1};
	vector<bool> name1 (nameArr1, nameArr1+sizeof(nameArr1)/sizeof(int));
	Vertex* vertex1 = new Vertex(name1);
	// neighbours of vertex 1
	int nameArr2[] = {1,1,0,1,1,1,1,1};
	vector<bool> name2 (nameArr2, nameArr2+sizeof(nameArr2)/sizeof(int));
	Vertex* vertex2 = new Vertex(name2);
	int nameArr3[] = {1,0,0,1,1,1,0,1};
	vector<bool> name3 (nameArr3, nameArr3+sizeof(nameArr3)/sizeof(int));
	Vertex* vertex3 = new Vertex(name3);
	// not a neighbour of vertex 1
	int nameArr4[] = {1,1,0,0,0,1,1,1};
	vector<bool> name4 (nameArr4, nameArr4+sizeof(nameArr4)/sizeof(int));
	Vertex* vertex4 = new Vertex(name4);
	// add vertices to the VertexDirectory
	VertexDirectory::AddVertex(vertex1);
	VertexDirectory::AddVertex(vertex2);
	VertexDirectory::AddVertex(vertex3);
	VertexDirectory::AddVertex(vertex4);
	// add vertices to the graph
	g.InsertVertex(vertex1);
	g.InsertVertex(vertex2);
	g.InsertVertex(vertex3);
	g.InsertVertex(vertex4);	
	// put all the vertices in the graph..
//	VertexDirectory::MoveAllVerticesToGraph((VertexContainer)&g);
	// find the vertices in the VertexDirectory
	TestUtils::TestResult res = TestUtils::VerifyIsTrue(NULL != VertexDirectory::GetStaticCopyVertex(vertex1->Name()),"vertex1 not found in VertexDirectory");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(NULL != VertexDirectory::GetStaticCopyVertex(vertex2->Name()),"vertex2 not found in VertexDirectory");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(NULL != VertexDirectory::GetStaticCopyVertex(vertex3->Name()),"vertex3 not found in VertexDirectory");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(NULL != VertexDirectory::GetStaticCopyVertex(vertex4->Name()),"vertex4 not found in VertexDirectory");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	Vertex* v1 = VertexDirectory::GetStaticCopyVertex(vertex1->Name());
	Vertex* v2 = VertexDirectory::GetStaticCopyVertex(vertex2->Name());
	Vertex* v3 = VertexDirectory::GetStaticCopyVertex(vertex3->Name());
	Vertex* v4 = VertexDirectory::GetStaticCopyVertex(vertex4->Name());
	// make sure that v1 is neighbours with v2 and v3 (in the graph), and not with v4
	res = TestUtils::VerifyIsTrue(true == v2->NeighboursInGraph(v1),"vertex1 not a neighbour of vertex2 in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(true == v3->NeighboursInGraph(v1),"vertex1 not a neighbour of vertex3 in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(false == v4->Neighbours(v1),"vertex1 is a neighbour of vertex4");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}

	// move vertex to a group
	v1->MoveToContainer(&group, false);
	// make sure that v1 is now not in the graph
	res = TestUtils::VerifyIsTrue(false == v1->IsInGraph(),"vertex1 is still in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	// make sure that v1 is neighbours with v2 and v3 (not in the graph), and not with v4
	res = TestUtils::VerifyIsTrue(true == v2->NeighboursNotInGraph(v1),"vertex1 not a neighbour of vertex2 in a group");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(true == v3->NeighboursNotInGraph(v1),"vertex1 not a neighbour of vertex3 in a group");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}


	return TestUtils::TestPassed;

}

#endif

// this test creates several vertices, adds them to the vertex directory, and then moves
// one of the vertices from the graph to a group and checks that the vertex (and its 
// neighbours) were updated accordingly
TestUtils::TestResult MoveVertexToGroup()
{
	Graph g;
	Group group(0);
	// create 4 vertices (n=7, w=4)
	int n=7;
	int w=4;
	bool nameArr1[] = {0,0,0,1,1,1,1};
	VertexDirectory::Clear();
	set<vector<bool>> *vertices = VertexDirectory::CreateAllVertices(n,w);
	VertexDirectory::FillVertexDirectory(vertices);
	vector<bool> name1 (nameArr1, nameArr1+sizeof(nameArr1)/sizeof(bool));
	Vertex* vertex1 = new Vertex(name1);
	// add vertex to the graph
	g.InsertVertex(vertex1);
	// save the vertex container for later use
	VertexContainer* container = vertex1->GetContainer();
	// find the vertex in the VertexDirectory
	TestUtils::TestResult res = TestUtils::VerifyIsTrue(NULL != VertexDirectory::GetStaticCopyVertex(vertex1->Name()),"vertex1 not found in VertexDirectory");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	// put all the vertex neighbours in the graph and in the VertexDirectory	
	set<vector<bool> > v1Neighbours = vertex1->GetNeighboursInGraph();
	set<vector<bool> >::iterator it;
	for (it = v1Neighbours.begin(); it != v1Neighbours.end(); it++)
	{
			Vertex* vertex = new Vertex(*it);
			g.InsertVertex(vertex);
	}

	//get the vertex from the vertex directory
	Vertex* v1 = VertexDirectory::GetStaticCopyVertex(vertex1->Name());
	// check that v1 is a nieghbour in the graph for 2 of its neighbours
	bool nameArr2[] = {1,0,0,1,1,1,0};
	vector<bool> name2 (nameArr2, nameArr2+sizeof(nameArr2)/sizeof(bool));
	bool nameArr3[] = {1,0,0,1,1,1,0};
	vector<bool> name3 (nameArr3, nameArr3+sizeof(nameArr3)/sizeof(bool));
	Vertex* v2 = VertexDirectory::GetStaticCopyVertex(name2);
	Vertex* v3 = VertexDirectory::GetStaticCopyVertex(name3);
	
	res = TestUtils::VerifyIsTrue(true == v2->NeighboursInGraph(v1),"vertex1 not a neighbour of vertex2 in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(true == v3->NeighboursInGraph(v1),"vertex1 not a neighbour of vertex3 in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	
	// move vertex to a group
	group.InsertNewVertex(v1);
	//v1->MoveToContainer(&group, false);
	// make sure that v1 is now not in the graph
	res = TestUtils::VerifyIsTrue(false == v1->IsInGraph(),"vertex1 is still in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	// make sure that v1 is neighbours with v2 and v3 (not in the graph)
	res = TestUtils::VerifyIsTrue(true == v2->NeighboursNotInGraph(v1),"vertex1 not a neighbour of vertex2 in a group");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(true == v3->NeighboursNotInGraph(v1),"vertex1 not a neighbour of vertex3 in a group");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}

	//move v1 back to the graph and check that it and its neighbours were updated
	v1->MoveToContainer(container, true);
	// make sure that v1 is now in the graph
	res = TestUtils::VerifyIsTrue(true == v1->IsInGraph(),"vertex1 is not in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	// make sure that v1 is neighbours with v2 and v3 (in the graph)
	res = TestUtils::VerifyIsTrue(true == v2->NeighboursInGraph(v1),"vertex1 not a neighbour of vertex2 in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}
	res = TestUtils::VerifyIsTrue(true == v3->NeighboursInGraph(v1),"vertex1 not a neighbour of vertex3 in the graph");
	if (res == TestUtils::TestFailed)
	{	// quit test
		return res;
	}


	return TestUtils::TestPassed;

}
